//
//  LocalCacheHandler.m
//  CToolBox
//
//  Created by SC on 16/12/12.
//  Copyright © 2016年 SC. All rights reserved.
//

#import "LocalCacheHandler.h"
#import "NSDate+Compare.h"



static LocalCacheHandler *shareInstance = nil;

NSString *const kCacheTableName = @"YJcache";


@interface LocalCacheHandler (){
    NSString *_DBPath;
}

@end

@implementation LocalCacheHandler

+ (LocalCacheHandler *)shareInstanceMethod
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shareInstance = [[LocalCacheHandler alloc] init];
    });
    return shareInstance;
    
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self initializeDBWithName:kDataBaseName];
    }
    return self;
}

#pragma mark - 打开数据库
- (void)initializeDBWithName:(NSString *)name
{
    if (!name) {
        NSLog(@"数据库名称不能为空");
        return ;
    }
    
    // 沙盒Docu目录
    NSString * docp = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES) objectAtIndex:0];
    _DBPath = [docp stringByAppendingString:[NSString stringWithFormat:@"/%@",name]];
    NSLog(@"数据库地址：%@",_DBPath);
    [self connect];
}

// 连接数据库 或 创建（不存在的话）
- (void)connect
{
    if (_queue == nil) {
        _queue = [FMDatabaseQueue databaseQueueWithPath:_DBPath];
    }
    
    [self createDataBase];
}

//创建数据表
- (void)createDataBase
{
    [_queue inDatabase:^(FMDatabase *db) {
        FMResultSet * resultSet = [db executeQuery:[NSString stringWithFormat:@"select count(*) from sqlite_master where type ='table' and name = '%@'",kCacheTableName]];
        
        [resultSet next];
        
        
        NSInteger count = [resultSet intForColumnIndex:0];
        
        
        BOOL existTable = count > 0;
        
        if (existTable) {
            // TODO:是否更新数据库
            NSLog(@"%@_数据库已经存在",kCacheTableName);
            
        } else {
            // TODO: 插入新的数据表
            NSString *sql=[NSString stringWithFormat:@"create table if not exists %@(key text ,expireTime text ,itemDict blob)",kCacheTableName];
            
            BOOL result = [db executeUpdate:sql];
            if (!result) {
                NSLog(@"%@_数据库创建失败",kCacheTableName);
                
            } else {
                //建立索引
                NSString *sql_index = [NSString stringWithFormat:@"CREATE INDEX index_%@_key ON %@(key)",kCacheTableName,kCacheTableName];
                BOOL crearIndexSucceed = [db executeUpdate:sql_index];
                NSLog(@"indexx===%@",sql_index);
                if(crearIndexSucceed){
                    NSLog(@"索引建立成功");
                }else{
                    NSLog(@"索引建立失败");
                }
                NSLog(@"%@_数据库创建成功",kCacheTableName);
                
            }
        }
        [resultSet close];
//        [db close];
    }];
    
}


#pragma mark - 查询
- (void)getValueWithKey:(NSString *)key complete:(void (^)(BOOL, id))complete
{
    if (!key) {
        return;
    }

    
    [_queue inDatabase:^(FMDatabase *db) {
//        [db open];
        
        NSString *query = [NSString stringWithFormat:@"SELECT * FROM %@",kCacheTableName];
        query = [query stringByAppendingFormat:@" WHERE key = '%@';",key];
        
        
        FMResultSet *resultSet = [db executeQuery:query];
        id object;
        NSDate *expireDate;
        
        while ([resultSet next]) {
            
            NSData *dictData = [resultSet objectForColumnName:@"itemDict"];
            object = [NSKeyedUnarchiver unarchiveObjectWithData:dictData];
            
            NSString *timeStr = [resultSet objectForColumnName:@"expireTime"];
            expireDate = [NSDate dateFromeString:timeStr];
            
        }
        
        NSDate *nowDate = [NSDate date];
        BOOL isExpired;
        
        if ([nowDate timeIntervalSinceDate:expireDate]<0.0) {
            
            isExpired = NO;
            
        }else{
            
            isExpired = YES;
        }
        
        if (complete) {
            complete(isExpired,object);
        }
        
        [resultSet close];
//        [db close];

    }];

}

#pragma mark - 清空表
- (void)clearTable
{
    __block BOOL result = NO;
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [_queue inDatabase:^(FMDatabase *db) {
//            [db open];
            NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@",kCacheTableName];
            result = [db executeUpdate:sql];
            NSLog(result?@"清空成功":@"清空失败");
//            [db close];
            
        }];
    });
    
    
}

#pragma mark - 删除表
- (void)deleteTable
{
    [_queue inDatabase:^(FMDatabase *db) {
//        [db open];
        __block BOOL result = NO;
        NSString *sql = [NSString stringWithFormat:@"DROP TABLE %@",kCacheTableName];
        result = [db executeUpdate:sql];
        NSLog(result?@"清空成功":@"清空失败");
//        [db close];
    }];
    
}


#pragma mark - 保存或更新
- (void)saveOrUpdateWithKey:(NSString *)key
                        dic:(NSDictionary *)dic
               expireLength:(long)expireLength
{
    [_queue inDatabase:^(FMDatabase *db) {
//        [db open];
        //检测是否存在，更新数据库数据
        NSString *check=[NSString stringWithFormat:@"SELECT * FROM %@ WHERE key ='%@'",kCacheTableName,key];
        
        // 更新数据库
        FMResultSet *resultSet = [db executeQuery:check];
        
        if (![resultSet next]) {
            //保存
            
            NSDate *expireDate = [[NSDate date] dateByAddingTimeInterval:expireLength];
            NSString *expireTime = [NSDate stringFromeDate:expireDate];
            //此处把字典归档成二进制数据直接存入数据库，避免添加过多的数据库字段
            NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dic];
            [db executeUpdateWithFormat:@"INSERT INTO YJcache (key , expireTime , itemDict) VALUES (%@, %@, %@)",key, expireTime, dictData];
            
        }
        else{
            //更新
            NSDate *expireDate = [[NSDate date] dateByAddingTimeInterval:expireLength];
            NSString *expireTime = [NSDate stringFromeDate:expireDate];
            NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dic];
            [db executeUpdateWithFormat:@"UPDATE YJcache SET expireTime=%@, itemDict=%@ WHERE key=%@",expireTime,dictData,key];
        }
        [resultSet close];
//        [db close];
    }];
}

#pragma mark - Private
//更新
- (void)updateWithKey:(NSString *)key
                  dic:(NSDictionary *)dic
         expireLength:(long)expireLength
{
    [_queue inDatabase:^(FMDatabase *db) {
//        [db open];
        NSDate *expireDate = [[NSDate date] dateByAddingTimeInterval:expireLength];
        NSString *expireTime = [NSDate stringFromeDate:expireDate];
        NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dic];
        [db executeUpdateWithFormat:@"UPDATE YJcache SET expireTime=%@, itemDict=%@ WHERE key=%@",expireTime,dictData,key];
        
//        [db close];
    }];
    
}

//保存
- (void)saveWithKey:(NSString *)key
                dic:(NSDictionary *)dic
       expireLength:(long)expireLength
{
    [_queue inDatabase:^(FMDatabase *db) {
//        [db open];
        NSDate *expireDate = [[NSDate date] dateByAddingTimeInterval:expireLength];
        NSString *expireTime = [NSDate stringFromeDate:expireDate];
        //此处把字典归档成二进制数据直接存入数据库，避免添加过多的数据库字段
        NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dic];
        [db executeUpdateWithFormat:@"INSERT INTO YJcache (key , expireTime , itemDict) VALUES (%@, %@, %@)",key, expireTime, dictData];
//        [db close];
    }];
    
}

- (void)resetExpireLength:(long)expireLength key:(NSString *)key
{
    [_queue inDatabase:^(FMDatabase *db) {
        //        [db open];
        //检测是否存在，更新数据库数据
        NSString *check=[NSString stringWithFormat:@"SELECT * FROM %@ WHERE key ='%@'",kCacheTableName,key];
        
        // 更新数据库
        FMResultSet *resultSet = [db executeQuery:check];
        
        if ([resultSet next]) {
            //保存
            
            NSDate *expireDate = [[NSDate date] dateByAddingTimeInterval:expireLength];
            NSString *expireTime = [NSDate stringFromeDate:expireDate];
            [db executeUpdateWithFormat:@"UPDATE YJcache SET expireTime=%@ WHERE key=%@",expireTime,key];
        }
        
        [resultSet close];
    }];

}

@end
